package ai.leinao.alarm.limit;

import ai.leinao.alarm.domain.RawAlarm;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.thread.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 告警通用处理
 *
 * @author zhong.wang
 * @date 2025/9/3
 **/
@Service
@Slf4j
public class AlarmLimitProcessor {
    /**
     * 告警分组收敛处理
     */
    private final AlarmGroupLimitProcessor alarmGroupLimitProcessor;

    /**
     * 告警处理线程池
     */
    private ThreadPoolExecutor workerExecutor;

    /**
     * 构造函数
     * @param alarmGroupLimitProcessor
     */
    public AlarmLimitProcessor(AlarmGroupLimitProcessor alarmGroupLimitProcessor) {
        initWorkExecutor();
        this.alarmGroupLimitProcessor = alarmGroupLimitProcessor;
    }

    /**
     * 初始化线程池
     */
    private void initWorkExecutor() {
        ThreadFactory threadFactory = new ThreadFactoryBuilder()
                .setUncaughtExceptionHandler((thread, throwable) -> {
                    System.out.println(throwable);
                })
                .setDaemon(true)
                .setNamePrefix("alerter-reduce-worker-%d")
                .build();
        workerExecutor = new ThreadPoolExecutor(2,
                2,
                10,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(),
                threadFactory,
                new ThreadPoolExecutor.AbortPolicy());
    }


    /**
     * 告警处理
     * @param alarm
     */
    public void reduceAndSendAlarm(RawAlarm alarm) {
        workerExecutor.execute(reduceAlarmTask(alarm));
    }

    /**
     * 告警处理任务
     * @param alarm
     * @return
     */
    Runnable reduceAlarmTask(RawAlarm alarm) {
        return () -> {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            try {
                String fingerprint = generateAlarmFingerprint(alarm);
                alarm.setFingerprint(fingerprint);
                alarmGroupLimitProcessor.processGroupAlert(alarm);
            } catch (Exception e) {
                log.error("告警处理失败: {}", e.getMessage(), e);
            }
            stopWatch.stop();
           // log.info("告警处理完成,耗时: {}", stopWatch.getTotalTimeMillis());
        };
    }


    /**
     * 生成告警指纹
     * @param alarm
     * @return
     */
    private String generateAlarmFingerprint(RawAlarm  alarm) {
        StringBuilder sb = new StringBuilder();
        sb.append("mainType"+":"+alarm.getMainType());
        sb.append(",");
        sb.append("subType"+":"+alarm.getSubType());
        sb.append(",");
        sb.append("alarmContent"+":"+alarm.getAlarmContent());
        sb.append(",");
        sb.append("alarmLevel"+":"+alarm.getAlarmLevel());
        sb.append(",");
        sb.append("stationId"+":"+alarm.getStationId());
        sb.append(",");
        sb.append("stationAreaId"+":"+alarm.getStationAreaId());
        sb.append(",");
        sb.append("deviceId"+":"+alarm.getDeviceId());
        return sb.toString();
    }


}
